package com.example.leetcode.tree.common;

import com.example.swing.BinaryTreeVisualizer;

public class TreePrinter {

    public static void main(String[] args) {
        TreeNode root = new TreeNode(1,
            new TreeNode(2, new TreeNode(4), new TreeNode(5)),
            new TreeNode(3, null, new TreeNode(6))
        );

        System.out.println("树形结构打印：");
        printPrettyTree(root);
        BinaryTreeVisualizer.show(root);
    }

    public static void printPrettyTree(TreeNode root) {
        int height = getHeight(root);
        int rows = height * 2 - 1;
        int cols = (int) Math.pow(2, height + 1) - 1;

        String[][] canvas = new String[rows][cols];
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                canvas[i][j] = " ";
            }
        }

        draw(root, canvas, 0, cols / 2, cols / 4);

        for (String[] row : canvas) {
            StringBuilder line = new StringBuilder();
            for (String ch : row) {
                line.append(ch);
            }
            System.out.println(line.toString().replaceAll("\\s+$", ""));
        }
    }

    private static void draw(TreeNode node, String[][] canvas, int row, int col, int gap) {
        if (node == null || row >= canvas.length || col < 0 || col >= canvas[0].length) return;

        canvas[row][col] = String.valueOf(node.val);

        int nextGap = Math.max(gap / 2, 1); // 保证 gap 不为 0

        if (node.left != null) {
            int slashCol = Math.max(0, col - gap);
            if (row + 1 < canvas.length)
                canvas[row + 1][slashCol] = "/";

            int leftCol = Math.max(0, col - gap * 2);
            draw(node.left, canvas, row + 2, leftCol, nextGap);
        }

        if (node.right != null) {
            int slashCol = Math.min(canvas[0].length - 1, col + gap);
            if (row + 1 < canvas.length)
                canvas[row + 1][slashCol] = "\\";

            int rightCol = Math.min(canvas[0].length - 1, col + gap * 2);
            draw(node.right, canvas, row + 2, rightCol, nextGap);
        }
    }

    private static int getHeight(TreeNode node) {
        if (node == null) return 0;
        return 1 + Math.max(getHeight(node.left), getHeight(node.right));
    }
}
